package com.demo.interview;

import java.util.concurrent.TimeUnit;

/**
 * 哲学家就餐问题 (死锁问题)
 * @author shenguangyang
 */
public class PhilosohperQuestion {
    public static void main(String[] args) throws Exception {
        ChopStick c0 = new ChopStick(0);
        ChopStick c1 = new ChopStick(1);
        ChopStick c2 = new ChopStick(2);
        ChopStick c3 = new ChopStick(3);
        ChopStick c4 = new ChopStick(4);

        Philosohper p0 = new Philosohper("p0", c0, c1);
        Philosohper p1 = new Philosohper("p1", c1, c2);
        Philosohper p2 = new Philosohper("p2", c2, c3);
        Philosohper p3 = new Philosohper("p3", c3, c4);
        Philosohper p4 = new Philosohper("p4", c4, c0);

        p0.start();
        p1.start();
        p2.start();
        p3.start();
        p4.start();
        TimeUnit.SECONDS.sleep(5);
    }
}

/**
 * 筷子
 */
class ChopStick {
    int index;

    public ChopStick(int index) {
        this.index = index;
    }
}

class Philosohper extends Thread  {
    String name;
    final ChopStick left;
    final ChopStick right;

    public Philosohper(String name, ChopStick left, ChopStick right) {
        this.name = name;
        this.left = left;
        this.right = right;
    }

    @Override
    public void run() {
        try {
            if (left.index % 2 == 0) {
                synchronized (left) {
                    TimeUnit.SECONDS.sleep(1 + left.index);
                    synchronized (right) {
                        TimeUnit.SECONDS.sleep(1);
                        System.out.println(name + " 哲学家吃完了");
                    }
                }
            } else {
                synchronized (right) {
                    TimeUnit.SECONDS.sleep(1 + left.index);
                    synchronized (left) {
                        TimeUnit.SECONDS.sleep(1);
                        System.out.println(name + " 哲学家吃完了");
                    }
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}